; (function () {
    return
    /**
   * @param {string} s
   * @return {number}
   */
    var lengthOfLongestSubstring = function (s) {
        if (s == "") return 0
        if (s.length == 1) return 1
        let obj = {}
        let num = 0
        let currentNum = 0
        for (let index = 0; index < s.length; index++) {
            let idx = index

            while (true) {

                let str = s[idx] === " " ? 'space' : s[idx]
                if (obj[str] !== undefined) {
                    obj = {}
                    num = Math.max(num, currentNum)
                    currentNum = 0
                    break
                } else {
                    obj[str] = true
                    currentNum++
                }

                idx++
                if (s[idx] === undefined) break
            }


        }
        return num
    };
    lengthOfLongestSubstring("abcabcbb")
    lengthOfLongestSubstring("bbbbb")
    lengthOfLongestSubstring("pwwkew")
    lengthOfLongestSubstring("au")



})();


// 官方答案 改变
; (function () {
    return
    var lengthOfLongestSubstring = function (s) {

        const occ = new Set();
        const n = s.length;
        let rk = 0, ans = 0;
        for (let i = 0; i < n; ++i) {
            if (i != 0) {
                // 这个相当于左指针向右移动一格.
                occ.delete(s.charAt(i - 1));
            }

            // 这个判断rk < n 右指针的下标不能超过字符长度
            // !occ.has(s.charAt(rk))
            // 保存的occ中不能有右指针指向的字符(就是不能重复).
            // 因为如果有对应的字符,说明右指针就是重复项.
            while (rk < n && !occ.has(s.charAt(rk))) {

                occ.add(s.charAt(rk));
                ++rk;
            }

            // 情况1,rk到了最后一项
            // 情况2,右指针为重复项时rk不在向右移动
            ans = Math.max(ans, rk - i);

            // 当rk碰到重复项的时候ans也获取到了最大值了.
            // 再循环时, 就是左指针向右移动的,一直移动到没有和右指针重复的数为止.
            // 右指针在继续移动.
        }
        return ans;
    };




})();

// 运行最快的解决方式
; (function () {
    // return
    /**
   * @param {string} s
   * @return {number}
   s = "abcabcbb"
   s = "bbbbb"
   s = "pwwkew"
   */

    var lengthOfLongestSubstring = function (s) {
        let index = 0, res = 0;
        const map = new Map();
        for (let i = 0; i < s.length; i++) {
            // 是否有s[i]这个数, 

            if (map.has(s[i])) {
                // index是无重复数的开始下标 
                // 这么做的原因是因为,
                // 当有重复时,应该舍弃重复下标自己,即重复下边之前的字符
                // map.get(s[i]) + 1为大时,
                // 说明重复字符串出现在index到i之间.
                // 需要更新index为map.get(s[i]) + 1

                // 当index为大时, 说明重复字符串在index前面
                // 在index前面不用管因为 在index到i之前s[i]它不重复
                index = Math.max(map.get(s[i]) + 1, index);
            }
            // 当没有重复数时
            // i++ 所以i - index + 1也会增大一个
            res = Math.max(res, i - index + 1);
            map.set(s[i], i)
        }
        console.log(res);
        return res
    };
    lengthOfLongestSubstring('abcdecfgh')
})();
; (function () {
    return
    /**
   * @param {string} s
   * @return {number}
   */
    var lengthOfLongestSubstring = function (s) {
        let res = []
        let max = 0
        for (let str of s) {

            // 判断当前的str是不是在数组里面
            // 如果在,就一直删除,直到当前str不在重复
            while (res.includes(str)) {
                res.shift()
            }
            // 当str不在重复时,
            // 把str添加到数组里面
            res.push(str)
            max = Math.max(max, res.length)

            // 这里主要是利用,只要出现重复,就删掉重复的元素和重复之前的元素.
            // 队列的思想,先进先出
        }
        console.log(max);
        return max
    };

    lengthOfLongestSubstring('abcdecfgh')
})();
